package xcmg.device.service.sluggishShard;

import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.sluggishShard.SluggishShardVO;
import xcmg.device.dao.entity.warehouse.WarehouseInventoryDO;
import xcmg.device.dao.mapper.sluggishShard.SluggishShardMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.FileUtil;
import xcmg.device.service.basic.MaterialsService;
import xcmg.device.service.company.CompanyInfoService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.basic.MaterialsVO;
import xcmg.device.service.warehouse.WarehouseInventoryService;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.PageHelperPlus;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author ZHANGK
 * @since 2020/6/5
 **/
@Service
public class SluggishShardService {

    @Autowired
    SluggishShardMapper sluggishShardMapper;

    @Autowired
    FastGenClient fastGenClient;

    @Autowired
    WarehouseInventoryService warehouseInventoryService;

    @Autowired
    private MaterialsService materialsService;

    @Autowired
    private HttpServletResponse response;

    @Value("${spring.file.download.path}")
    private String filePath;

    private String templateExcelFileName = "sluggishShardDetail.xlsx";

    @Autowired
    CompanyInfoService companyInfoService;


    public PageCommonVO getInsertList(SearchCommonVO<SluggishShardVO> condition) {
        PageCommonVO<SluggishShardVO> pageCommonVO = new PageCommonVO<>();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<SluggishShardVO> list = sluggishShardMapper.getInsertList(condition.getFilters().getOrgId());
        pageCommonVO.setPageInfo(new PageInfo(list));
        pageCommonVO.setPageInfoList(list);
        return pageCommonVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode insert(SluggishShardVO sluggishShardVO) {
        if (sluggishShardVO.getUnsalableQty().compareTo(sluggishShardVO.getAmount()) > 0) {
            return ErrorCode.UnsalabelQtyError;
        }
        ActionResult<String> genResult = fastGenClient.textGuid();
        if (genResult == null || genResult.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }
        sluggishShardVO.setId(genResult.getValue());
        boolean result = sluggishShardMapper.insert(sluggishShardVO);
        if (result) {
            //回写库存表
            warehouseInventoryService.updateSluggishFlagByMaterialNoAndOrgId(sluggishShardVO.getMaterialNo(), sluggishShardVO.getOrgId(), "1");
        }
        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public FunctionResult importExcel(InputStream in, String orgId) throws IOException {
        FunctionResult result = new FunctionResult();
        XSSFWorkbook wb = new XSSFWorkbook(in);
        XSSFSheet sheet = wb.getSheetAt(0);
        int totalRow = sheet.getLastRowNum();
        if (totalRow < 2) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        int totalCell = sheet.getRow(2).getLastCellNum();
        if (totalCell != 6) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }

        boolean success = false;
        List<SluggishShardVO> errorDetailList = Lists.newArrayList();
        for (int i = 2; i <= totalRow; i++) {
            XSSFRow curRow = sheet.getRow(i);
            SluggishShardVO sluggishShardVO = new SluggishShardVO();
            SluggishShardVO errorDetail = new SluggishShardVO();
            if (curRow == null) {
                errorDetail.setErrorRow(i + 1);
                errorDetail.setRemarks("数据为空");
                errorDetailList.add(errorDetail);
                continue;
            }
            String materialNo = getCellValue(curRow, 1);
            if (ObjectUtils.isEmpty(materialNo)) {
                errorDetail.setErrorRow(i + 1);
                errorDetail.setRemarks("零件编码为空");
                errorDetailList.add(errorDetail);
                continue;
            }
            //String materialName = getCellValue(curRow, 2);
            //String unit = getCellValue(curRow, 3);
            MaterialsVO materialsVO = materialsService.itemByNo(materialNo, orgId);
            if (ObjectUtils.isEmpty(materialsVO)) {
                errorDetail.setErrorRow(i + 1);
                errorDetail.setRemarks("零件信息不存在");
                errorDetailList.add(errorDetail);
                continue;
            }
            String unsalableQty = getCellValue(curRow, 4);
            String unsalablePrice = getCellValue(curRow, 5);
            if (ObjectUtils.isEmpty(unsalableQty)){
                errorDetail.setErrorRow(i + 1);
                errorDetail.setRemarks("呆滞数量必填");
                errorDetailList.add(errorDetail);
                continue;
            }
            if (ObjectUtils.isEmpty(unsalablePrice)){
                errorDetail.setErrorRow(i + 1);
                errorDetail.setRemarks("滞销价格必填");
                errorDetailList.add(errorDetail);
                continue;
            }
            BigDecimal unsalableQtyDec = ObjectUtils.isEmpty(unsalableQty) ? BigDecimal.ZERO : new BigDecimal(unsalableQty);
            BigDecimal unsalablePriceDec = ObjectUtils.isEmpty(unsalablePrice) ? BigDecimal.ZERO : new BigDecimal(unsalablePrice);
            sluggishShardVO.setMaterialNo(materialNo);
            sluggishShardVO.setMaterialName(materialsVO.getMaterialsDes());
            sluggishShardVO.setUnsalableQty(unsalableQtyDec);
            sluggishShardVO.setUnsalablePrice(unsalablePriceDec);
            sluggishShardVO.setOrgId(orgId);
            BigDecimal amount = warehouseInventoryService.selectByMaterialNoAndOrgId(materialNo, orgId).stream().map(WarehouseInventoryDO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            if (unsalableQtyDec.compareTo(amount) > 0) {
                errorDetail.setErrorRow(i + 1);
                errorDetail.setRemarks("滞销数量不能大于库存数量");
                errorDetailList.add(errorDetail);
                continue;
            }
            sluggishShardVO.setAmount(amount);
            List<SluggishShardVO> srcList = sluggishShardMapper.selectBymaterialNo(materialNo);
            if (!ObjectUtils.isEmpty(srcList)) {
                sluggishShardVO.setId(srcList.get(0).getId());
                success = sluggishShardMapper.updateById(sluggishShardVO);
            } else {
                String id = fastGenClient.textGuid().getValue();
                if (ObjectUtils.isEmpty(id)) {
                    errorDetail.setRemarks("主键生成失败");
                    errorDetail.setErrorRow(i + 1);
                    errorDetailList.add(errorDetail);
                    continue;
                }
                sluggishShardVO.setId(id);
                success = sluggishShardMapper.insert(sluggishShardVO);
            }
            if (!success) {
                errorDetail.setRemarks("保存失败");
                errorDetail.setErrorRow(i + 1);
                errorDetailList.add(errorDetail);
                continue;
            }
        }

        if (ObjectUtils.isEmpty(errorDetailList)) {
            result.setCode(ErrorCode.Success);
        } else {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue(errorDetailList);
        }
        return result;
    }

    private String getCellValue(Row curRow, int i) {
        String value = "";
        if (curRow.getCell(i) != null) {
            curRow.getCell(i).setCellType(CellType.STRING);
            value = curRow.getCell(i).getStringCellValue();
        }
        return value;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode update(SluggishShardVO sluggishShardVO) {
        List<WarehouseInventoryDO> inventoryDOS = warehouseInventoryService.selectByMaterialNoAndOrgId(sluggishShardVO.getMaterialNo(), sluggishShardVO.getOrgId());
        BigDecimal amount = inventoryDOS.stream().map(WarehouseInventoryDO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (sluggishShardVO.getUnsalableQty().compareTo(amount) > 0) {
            return ErrorCode.UnsalabelQtyError;
        }
        boolean result = sluggishShardMapper.updateById(sluggishShardVO);
        if (result) {
            return ErrorCode.Success;
        }
        return ErrorCode.Failure;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode deleteById(String id) {
        SluggishShardVO sluggishShardVO = sluggishShardMapper.selectById(id);
        boolean result = sluggishShardMapper.deleteById(id);
        if (result) {
            //回写库存表
            warehouseInventoryService.updateSluggishFlagByMaterialNoAndOrgId(sluggishShardVO.getMaterialNo(), sluggishShardVO.getOrgId(), "0");
            return ErrorCode.Success;
        }
        return ErrorCode.Failure;
    }

    public PageCommonVO<SluggishShardVO> list(SearchCommonVO<SluggishShardVO> condition) {
        PageCommonVO<SluggishShardVO> pageCommonVO = new PageCommonVO<>();
        if (!ObjectUtils.isEmpty(condition.getFilters().getMaterialNos())){
            List<String> materialNoList = Arrays.asList(condition.getFilters().getMaterialNos().split(","));
            condition.getFilters().setMaterialNoList(materialNoList);
        }
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<SluggishShardVO> list = sluggishShardMapper.list(condition.getFilters());
        setCompanyName(list);
        pageCommonVO.setPageInfo(new PageInfo<>(list));
        pageCommonVO.setPageInfoList(list);
        return pageCommonVO;
    }

    public void downloadImportExcel() throws Exception {
        FileUtil.downLoadFile(response, filePath, templateExcelFileName);
    }

    public void export(String[] ids) throws Exception {
        List<SluggishShardVO> sluggishShardVOList = sluggishShardMapper.selectBatchByIds(Arrays.asList(ids));
        setCompanyName(sluggishShardVOList);
        String title = "呆滞共享数据导出";
        String[] rowsName = new String[]{"序号", "代理商名称", "零件编码", "零件名称", "滞销数量", "滞销价格"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        for (int i = 0; i < sluggishShardVOList.size(); i++) {
            SluggishShardVO sluggishShardVO = sluggishShardVOList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = sluggishShardVO.getOrgName();
            objs[2] = sluggishShardVO.getMaterialNo();
            objs[3] = sluggishShardVO.getMaterialName();
            objs[4] = sluggishShardVO.getUnsalableQty().toString();
            objs[5] = sluggishShardVO.getUnsalablePrice().toString();
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private void setCompanyName(List<SluggishShardVO> sluggishShardVOList) {
        Set<String> orgIds = new HashSet<>();
        for (SluggishShardVO sluggishShardVO : sluggishShardVOList) {
            orgIds.add(sluggishShardVO.getOrgId());
        }
        if (ObjectUtils.isEmpty(orgIds)) {
            return;
        }
        List<CompanyInfoDO> companyInfoDOS = companyInfoService.selectBatchByOrgIds(new ArrayList<>(orgIds));
        if (ObjectUtils.isEmpty(companyInfoDOS)) {
            return;
        }

        Map<String, CompanyInfoDO> companyInfoDOMap = companyInfoDOS.stream().collect(Collectors.toMap(CompanyInfoDO::getOrgId, a -> a, (k1, k2) -> k1));
        for (SluggishShardVO sluggishShardVO : sluggishShardVOList) {
            if (companyInfoDOMap.containsKey(sluggishShardVO.getOrgId())) {
                sluggishShardVO.setOrgName(companyInfoDOMap.get(sluggishShardVO.getOrgId()).getCompanyName());
            }
        }
    }

    public void exportAll(SluggishShardVO sluggishShardVO) throws Exception {
        if (!ObjectUtils.isEmpty(sluggishShardVO.getMaterialNos())){
            List<String> materialNoList = Arrays.asList(sluggishShardVO.getMaterialNos().split(","));
            sluggishShardVO.setMaterialNoList(materialNoList);
        }
        List<SluggishShardVO> sluggishShardVOList = sluggishShardMapper.list(sluggishShardVO);
        setCompanyName(sluggishShardVOList);
        String title = "呆滞共享数据导出";
        String[] rowsName = new String[]{"序号", "代理商名称", "零件编码", "零件名称", "滞销数量", "滞销价格"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        for (int i = 0; i < sluggishShardVOList.size(); i++) {
            SluggishShardVO model = sluggishShardVOList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = model.getOrgName();
            objs[2] = model.getMaterialNo();
            objs[3] = model.getMaterialName();
            objs[4] = model.getUnsalableQty().toString();
            objs[5] = model.getUnsalablePrice().toString();
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

}
